const FUN = require('../comm/func');
const rCache = require('../model/redis_cache');
const DB = require('../model/model_data');
const dbHelp = require('../comm/db-helper');
const timLib = require('../comm/time-lib');
const PMR = require('../utils/policyManger');

module.exports = class Summary
{
  //将数据库选项缓存到redis
  //policy 来自数据库的记录
  //opts 数据库json字段的解析对象
  //CacheCallback 存储执行函数
  static InitCache(policy,opts,CacheCallback)
  {
    let obj=PMR.baseParam(policy);//即将缓存到redis的参数

    //检查json选项
    if( (parseInt(opts.period)==0) )
    {
      console.error('wrong summary policy',policy.id);
      return false;
    }

    //校验策略是否属于自己
    let policyNode=rCache.N_Policy+':'+policy.master;
    rCache.get(policyNode,opts.target_id,'hwid').then((val)=>{
      if(policy.master!=val) PMR.disablePolicy(policy.id);//停止处理策略
    })

    //json options参数存储
    obj.target_id = opts.target_id;//目标策略ID
    obj.period = opts.period;//加和周期
    obj.record_limit = policy.record_limit;//数据库条数上限

    //if(opts.out_tab) obj.out_tab = opts.out_tab;//var变量输出数据表名

    //数据库处理
    dbHelp.createTab(obj.table,policy.uid);
    //dbHelp.createTab(obj.out_tab,policy.uid);

    //缓存主站参数
    obj.hwid = policy.master;
    CacheCallback(policy.id,policy.master,obj);//记录到缓存
  }//end InitCache

  //modbus数据总分析
  // topic = {project,devType,func,devId}
  // dConf即InitCache中的obj
  // dataBuf即mq消息内容，buf对象
  static DataIn(topic, dConf, dataBuf)
  {
    if(topic.func != 'tx') return;//只接受tx端点的数据，相当于轮询
    //if(dConf.enable!=1) return;

    let nowStamp=timLib.NowStamp();
    let policyNode=rCache.N_Policy+':'+dConf.hwid;
    let gapMs=3600;

    //计算轮询周期
    if(dConf.period=='day') gapMs=3600;
    else if(dConf.period=='week') gapMs=3600*4;
    else if(dConf.period=='mon') gapMs=3600*8;
    else return;

    rCache.get(policyNode,dConf.policy_id,'last').then((val)=>{
      if(val)
      {
        if((nowStamp-val)>=(gapMs*1000))//到了轮询时间了
        {
          this.periodCalc(dConf);
          rCache.set(policyNode,dConf.policy_id,{'last':nowStamp});//记录当下时间
        }
      }
      else //last不存在
      {
        rCache.set(policyNode,dConf.policy_id,{'last':nowStamp});//记录当下时间
      }
    })
  }//end function DataIn


  //将数据表的数据进行加和计算并存储
  static periodCalc(dConf)
  {
    let stampEnd=0;
    let stampStart=0;

    if(dConf.period=='day')
    {
      stampStart=timLib.PrevRounding(86400);//取整
      stampEnd=timLib.Rounding(86400);//取整
    }
    else if(dConf.period=='week')
    {
      let d=new Date();
      let day=d.getDay();
      let stamp=d.getTime();

      stamp=timLib.Rounding(86400,stamp);//取整
      stampEnd=stamp-day*86400*1000;
      stampStart=stampEnd-7*86400*1000;
    }
    else if(dConf.period=='mon')
    {
      let d=new Date();
      let thisMon=d.setDate(1);
      let prevMon=d.setMonth(d.getMonth()-1);

      stampStart=timLib.Rounding(86400,prevMon);//取整
      stampEnd=timLib.Rounding(86400,thisMon);//取整
    }

    //查询本周期是否已经计算过
    DB.findByStamp(dConf.uid,dConf.table,dConf.policy_id,stampEnd-1000).then(res=>{
      if(!res){ //记录不存在
        DB.findByDuration(dConf.uid,dConf.table,dConf.target_id,stampStart,stampEnd).then(res=>{//获取上个周期所有记录
          pcyLog('[%d][%d] summary',dConf.policy_id,dConf.hwid,timLib.Stamp2Str(stampStart),timLib.Stamp2Str(stampEnd),res.length);
          if(res.length) this.recordSumCalc(dConf,res,stampEnd);
        })//end db.findByDuration
      }//end if !res
    })//end db.findByStamp
  }

  //将数据表的记录相加
  static recordSumCalc(dConf,rcds,stamp)
  {
    let sum={};
    let keys=Object.keys(JSON.parse(rcds[0].json));

    //计算历史记录的和
    keys.some(k=>{sum[k]=0});//初始化sum为0
    rcds.some(one=>{
      let jData=JSON.parse(one.json);
      keys.some(k=>{
        sum[k]+=Number(jData[k])*1000;
      })
    })
    keys.some(k=>{sum[k]/=1000});//基数1000避免js数据精度问题

    //存储到数据表
    DB.newRcd(dConf.uid, dConf.table, 'hwid,policy_id,addr,json,stamp',
              [dConf.hwid, dConf.policy_id, rcds[0].addr, JSON.stringify(sum), stamp-1000]);
    PMR.policyInform('update',dConf);
  }//end recordSumCalc



} //end class Modbus